# Create your views here.
'''
前端
    拼接一个url，然后给img img发起请求
    url=http://ip:port:img_codes/uuid/


后端
    请求       接收路由中的uuid
    业务逻辑   生成图片验证码和图片二进制   通过redis把图片验证码保存起来
    响应       返回图片的二进制
    路由        image_codes/uuid/



    步骤
            - 接收路由中的uuid
            - 生成图片验证码 和二进制
            - redis 保存图片验证码
            - 返回图片二进制

'''
from django.http import HttpResponse
from django.views import View


# --------------------------------------------图片验证码的生成保存到redis
# 前端点击验证码图片时
# 发起请求 http://www.meiduo.site:8000/image_codes/<uuid>/
# 后端生成一个验证码
class ImageCodeView(View):
    # 前端中的img标签发送的是一个get请求  来获取一个图片的验证码
    # uuid由前端生成
    def get(self, request, uuid):
        from libs.captcha.captcha import captcha
        # 1 接收路由中的uuid
        # 2 生成图片验证码和二进制
        # text 是图片验证码的内容 img  是图片的二进制
        text, img = captcha.generate_captcha()
        print(text)
        # 3 redis保存图片验证码
        # redis的连接
        from django_redis import get_redis_connection
        redis_cli = get_redis_connection('code')
        # 指令操作
        # setex(self, name, time, value):
        redis_cli.setex(uuid, 300, text)
        # 4 返回图片二进制
        # content_type是响应体数据类型
        # content_type语法形式 大类/小类  image/png
        return HttpResponse(img, content_type='image/png')


# -------------------------------------------短信验证码
''''
前端
    当用户输入完手机号 验证码 前端发送一个axios请求
    http://www.meiduo.site:8000/sms_codes/17594842359/?image_code=YVFO&image_code_id=d1abd321-f60f-45e5-b7d4-c45fd7fd088c


后端
    请求        接收请求 获取请求参数（路由有手机号  查询字符串中由验证码 和 uuid ）
    业务逻辑     验证参数，验证图片验证码，生成短信验证码，保存短信验证码 发送短信验证码
    响应       {'code':0,'errmsg':'ok'}
    路由        GET       http://www.meiduo.site:8000/sms_codes/17594842359/?image_code=YVFO&image_code_id=d1abd321-f60f-45e5-b7d4-c45fd7fd088c



    步骤     
            - 接收请求参数
            - 验证参数
            - 验证图片验证码
            - 生成短信验证码
            - 保存短信验证码 
            - 发送短信验证码
            - 返回响应
'''

from django.http import JsonResponse


# 在前端点击发送按钮的时候  会请求这个url  后端给手机发送验证码
# http://www.meiduo.site:8000/sms_codes/17320022875/?image_code=YVFO&image_code_id=d1abd321-f60f-45e5-b7d4-c45fd7fd088c
class SmeCodeView(View):
    def get(self, request, mobile):
        # 获取查询字符串中的内容
        image_code = request.GET.get('image_code')  # 这是用户输入的验证码信息
        uuid = request.GET.get('image_code_id')  # 这是前端生成的uuid  会在后端生成验证码图片 以及  验证码
        print(type(image_code))  # str
        # 验证参数
        if not all([image_code, uuid]):
            return JsonResponse({'code': 400, 'errmsg': '参数不全'})
        # 验证图片验证码
        # 连接redis
        from django_redis import get_redis_connection
        redis_cli = get_redis_connection('code')
        redis_img_code = redis_cli.get(uuid)  # 这是在redis中uuid对应的验证码
        print(type(redis_img_code))  # bytes
        if redis_img_code is None:
            return JsonResponse({'code': 400, 'errmsg': '验证码过期'})
        # 进行验证码的对比
        if redis_img_code.decode() != image_code:
            return JsonResponse({'code': 400, 'errmsg': '验证码不正确'})
        # 提取发送短信的标记 看看是不是已经发送了

        send_flag = redis_cli.get('send_flag_%s' % mobile)
        if send_flag is not None:
            return JsonResponse({'code': 400, 'errmsg': '不要频繁发送短信'})
        # 生成短信验证码
        # sms_code_server = str(randint(1000, 9999))
        sms_code_server = '1234'

        # 管道
        # 1。新建一个管道
        pipeline = redis_cli.pipeline()
        # 2。管道收集指令
        # 保存短信验证码
        pipeline.setex(mobile, 300, sms_code_server)
        # 添加一个发送标记 有效期为60秒
        pipeline.setex('send_flag_%s' % mobile, 60, 1)
        # 3。管道执行指令
        pipeline.execute()  # 此时短信验证码已经开始倒计时 但是前端还没有收到响应
        # 发送短信验证码   后端是需要时间进行短信的发送的 会造成前端页面的延迟  发送成功之后 前端才会收到响应
        # ----------------应该采用异步发送  将返回响应和 发送短信分开---------------
        # 生产者（客户端） 生产任务  即发送短信 这个任务
        # -----------------------------------异步操作------------------------------------------
        # 消费者 send_sms(sms_code_server, mobile)  这个函数执行这个需求
        # from libs.duanxin.send import send_sms
        # send_sms(sms_code_server, mobile)
        from celery_tasks.sms.tasks import celery_send_sms_code
        celery_send_sms_code.delay(sms_code_server, mobile)  # 放到队列中
        # 返回响应
        return JsonResponse({'code': 0, 'errmsg': 'ok'})

    # 在你前端输入完短信验证码 点击注册 发送一个post请求
    def post(self, request, mobile):
        # 获取提交的验证码信息
        sms_code_client = request.POST.get('sms_code')
        from django_redis import get_redis_connection
        redis_cli = get_redis_connection('code')
        sms_code_server = redis_cli.get(mobile).decode()
        if not sms_code_server:
            return JsonResponse({'code': 400, 'errmsg': '短信验证码失效'})
        # 对比用户输入的和服务端存储的短信验证码是否一致
        if sms_code_client != sms_code_server:
            return JsonResponse({'code': 400, 'errmsg': '短信验证码有误'})
        return JsonResponse({'code': 0, 'errmsg': '成功'})


'''
生产者
消费者
队列（中间人）
Celery---将这三者实现
'''
